package com.yihusitian.zsxq.sg.generator;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.google.common.collect.Sets;
import com.yihusitian.zsxq.sg.config.BaseClassInfo;
import com.yihusitian.zsxq.sg.filter.Filter;
import com.yihusitian.zsxq.sg.filter.FilterChain;
import com.yihusitian.zsxq.sg.util.CommonInfoHolder;
import com.yihusitian.zsxq.sg.util.GenerateConfigHolder;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description 代码生成接口
 * @Author LeeHo
 * @Date 2020/8/26 14:25
 */
public interface SourceGenerator extends Filter {

    GenerateConfigHolder generateConfigHolder = CommonInfoHolder.generateConfigHolder;

    String DOT_REGEX = "\\.";

    String TAB_NEW_LINE = "\n\t";

    String TAB = "\t";

    String NOTE = "//";

    String IMPORT_TEMPLATE = "import %s.%s;";

    String CLASS_COMMENT = "/**\n" +
            " * @Description TODO\n" +
            " * @Author ${AUTHOR}\n" +
            " * @Date ${FILE_CREATE_TIME}\n" +
            " */";


    /**
     *
     * @return
     */
    BaseClassInfo getBaseClassInfo();

    /**
     * 代码模板名称
     *
     * @return
     */
    default String getCodeTemplateName() {
        return getBaseClassInfo().getCodeTemplateName();
    }

    /**
     * 获取包路径
     *
     * @return
     */
    default String getPackagePath() {
        return getBaseClassInfo().getPackagePath();
    }

    /**
     * 返回类名称
     *
     * @return
     */
    default String getClassName() {
        BaseClassInfo baseClassInfo = getBaseClassInfo();
        return CommonInfoHolder.getCurrentBusinessName() + baseClassInfo.getClassNameSuffix();
    }

    /**
     * 获取模板内容
     *
     * @return
     */
    default String getCodeTemplate() {
        return generateConfigHolder.getCodeTemplateMap().get(getCodeTemplateName());
    }

    /**
     * 获取当前系统的用户
     *
     * @return
     */
    default String getAuthor() {
        return StringUtils.isNotBlank(generateConfigHolder.getBaseinfo().getAuthor()) ? generateConfigHolder.getBaseinfo().getAuthor() : System.getProperty("user.name");
    }

    /**
     * 获取类注释
     *
     * @return
     */
    default String getClassComment() {
        return CLASS_COMMENT.replace("${AUTHOR}", getAuthor()).replace("${FILE_CREATE_TIME}", DateUtil.formatDateTime(new Date()));
    }

    /**
     * 获取额外导入的
     *
     * @return
     */
    default Set<String> getImportSet() {
        return Sets.newHashSet();
    }

    /**
     * 文件内容
     *
     * @return
     */
    default String getFileContent() {
        String mainContent = getMainContent();
        String importContent = getImportSet().stream().collect(Collectors.joining(StrUtil.LF));
        String businessName = CommonInfoHolder.getCurrentBusinessName();
        return getCodeTemplate()
                .replace("${IMPORT_CONTENT}", importContent)
                .replace("${CLASS_COMMENT}", getClassComment())
                .replace("${TABLE_NAME}", CommonInfoHolder.getCurrentTableInfo().getName())
                .replace("${API_MODEL_DESCRIPTION}", CommonInfoHolder.getCurrentTableComment())
                .replace("${MAIN_CONTENT}", mainContent)
                .replace("${ISERVICE_NAME}", businessName + generateConfigHolder.getServiceInfo().getClassNameSuffix())
                .replace("${MAPPER_NAME}", businessName + generateConfigHolder.getMapperInfo().getClassNameSuffix())
                .replace("${SERVICE_IMPL_NAME}", businessName + generateConfigHolder.getServiceImplInfo().getClassNameSuffix())
                .replace("${VO_NAME}", businessName + generateConfigHolder.getVoInfo().getClassNameSuffix())
                .replace("${DTO_NAME}", businessName + generateConfigHolder.getDtoInfo().getClassNameSuffix())
                .replaceAll("\\$\\{DO_NAME\\}", businessName + generateConfigHolder.getDoInfo().getClassNameSuffix())
                ;
    }

    /**
     * 获取主内容
     *
     * @return
     */
    default String getMainContent() {
        return StringUtils.EMPTY;
    }

     /**
     * 生成源文件
     */
    default void generateSourceFile() {
        String fileContent = getFileContent();
        String projectLocation = generateConfigHolder.getBaseinfo().getProjectLocation();
        String javaFileLocation = generateConfigHolder.getBaseinfo().getJavaFileLocation();
        String packagePath = getPackagePath();
        String outputDir = new StringBuilder().append(projectLocation).append(StrUtil.SLASH).append(javaFileLocation).append(packagePath.replaceAll(DOT_REGEX, StrUtil.SLASH)).toString();
        String fileName = getClassName() + StringPool.DOT_JAVA;
        //只针对DO对象处理
        String serialVersionUIDLine = getSerialVersionUIDLine(fileContent, packagePath, fileName);
        if (StringUtils.isNotEmpty(serialVersionUIDLine)) {
            fileContent = fileContent.replace("//serialVersionUID", serialVersionUIDLine);
        }
        File file = new File(outputDir, fileName);
        boolean coverOldFile = generateConfigHolder.getBaseinfo().isCoverOldFile();
        if (file.exists()) {
            if (coverOldFile) {
                file.delete();
            } else {
                System.out.println(String.format("文件【%s】已经存在", file.getName()));
                return;
            }
        }
        FileUtil.writeString(fileContent, new File(outputDir, fileName), Charset.forName("UTF-8"));
    }

    /**
     *
     * @param sourceContent
     * @param packagePath
     * @param fileName
     * @return
     */
    default String getSerialVersionUIDLine(String sourceContent, String packagePath, String fileName) {
        return StringUtils.EMPTY;
    }

    /**
     *
     * @param filterChain
     */
    default void doFilter(FilterChain filterChain) {
        //生成源文件
        generateSourceFile();
        filterChain.doFilter(filterChain);
    }
}
